package pres.moling.common.tool;


import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;


/**
 * 类型转换工具类
 */
public interface ConvertHelper {

    /**
     * 基本类型转换器
     */

    /**
     * 将map数据转换为JavaBean
     *
     * @param map   携带数据的map
     * @param clazz 要转换的类
     * @param <T>   转换后的类
     */
    static <T> T mapToBean(Map<String, Object> map, Class<T> clazz) {
        T result = null;
        try {
            result = clazz.getDeclaredConstructor().newInstance();
            for (Field field : clazz.getDeclaredFields()) {
                field.setAccessible(true);
                field.set(result, map.get(field.getName()));
            }
        } catch (IllegalAccessException | NoSuchMethodException | InstantiationException |
                 InvocationTargetException e) {

            throw new RuntimeException("map 转 bean 失败", e);
        }
        return result;
    }

    /**
     * 对象转换为 String
     *
     * @param obj 待转换数据对象
     * @return 转换结果
     */
    static String castToStr(Object obj) {
        return obj == null ? null : String.valueOf(obj);
    }

    /**
     * 对象转换为 Integer
     *
     * @param obj 待转换数据对象
     * @return 转换结果
     */
    static Integer castToInt(Object obj) {
        if (obj == null) {
            return null;
        }
        if (obj instanceof Integer integer) {
            return integer;
        }
        if (obj instanceof String str) {
            return Integer.getInteger(str);
        }
        if (obj instanceof Number number) {
            return number.intValue();
        }
        throw new ToolException("类：" + obj.getClass() + "无法转换为Integer");
    }

    /**
     * 对象转换为 Boolean
     *
     * @param obj 待转换数据对象
     * @return 转换结果
     */
    static Boolean castToBoolean(Object obj, String... okStr) {
        if (Objects.isNull(obj)) {
            return null;
        }

        if (obj instanceof Integer num) {
            return num != 0;
        }
        if (obj instanceof Long num) {
            return num != 0;
        }
        if (obj instanceof String str) {
            if ("ok".equals(str)) {
                return true;
            }
            if ("success".equals(str)) {
                return true;
            }
            if ("Yes".equalsIgnoreCase(str)) {
                return true;
            }
            if (Objects.nonNull(okStr)) {
                return Arrays.asList(okStr).contains(str);
            }
            return false;
        }
        throw new ToolException("类：" + obj.getClass() + "无法转换为Boolean");
    }

    /**
     * 对象转换为 Date
     *
     * @param obj 待转换数据对象
     * @return 转换结果
     */
    static Date castToDate(Object obj) {
        if (obj == null) {
            return null;
        }
        if (obj instanceof Date date) {
            return date;
        }
        if (obj instanceof Calendar date) {
            return date.getTime();
        }
        if (obj instanceof LocalDate date) {
            return DateHelper.coverDate(date);
        }
//        if (obj instanceof LocalDateTime dateTime) {
//            return DateHelper.coverDate(dateTime);
//        }
//        if (obj instanceof String s) {
//            return DateUtil.parseDate(s);
//        }
        throw new RuntimeException("cant not transform to date , : " + obj);
    }

    /**
     * 对象转换为 LocalDate
     *
     * @param obj 待转换数据对象
     * @return 转换结果
     */
    static LocalDate castLocalDate(Object obj) {
        if (obj == null) {
            return null;
        }
        if (obj instanceof Date date) {
            return DateHelper.coverLocalDate(date);
        }
        if (obj instanceof LocalDate date) {
            return date;
        }
        if (obj instanceof LocalDateTime time) {
            return time.toLocalDate();
        }
//        if (obj instanceof String str) {
//            return DateHelper.parseLocalDate(str);
//        }
        throw new RuntimeException("cant not transform to LocalDate");
    }

    /**
     * 对象转换为 LocalDateTime
     *
     * @param obj 待转换数据对象
     * @return 转换结果
     */
    static LocalDateTime castLocalDateTime(Object obj) {
        if (obj == null) {
            return null;
        }
//        if (obj instanceof Date date) {
//            return DateHelper.coverLocalDateTime(date);
//        }
        if (obj instanceof LocalDate date) {
            return date.atTime(0, 0);
        }
        if (obj instanceof LocalDateTime time) {
            return time;
        }
//        if (obj instanceof String str) {
//            return DateHelper.parseLocalDateTime(str);
//        }
        throw new RuntimeException("cant not transform to LocalDateTime");
    }
}
